#pragma once

#include <gofcl_usbfs_depctl.h>
#include <gofcl_usbfs_ep_r.h>
#include <sys_usb.h>

typedef enum {
	USBFS_EOFRM_EVEN = 0,
	USBFS_EOFRM_ODD = 1,
	USBFS_DPID_DATA0 = 0,
	USBFS_DPID_DATA1 = 1,
} usbfs_eofrm_dpid_e;

typedef struct {
	u32_s max_pkt_len : 11;
	u32_s : 4;
	u32_s active : 1;
	usbfs_eofrm_dpid_e even_odd_pid : 1;
	u32_s nak_stat : 1;
	usb_trans_type_e ep_type : 2;
	u32_s snoop_mode_en : 1;
	u32_s stall_en : 1;
	u32_s trans_fifo_no : 4;
	u32_s clear_nak : 1;
	u32_s set_nak : 1;
	u32_s set_even_data0 : 1;
	u32_s set_odd_data1 : 1;
	u32_s ep_di : 1;
	u32_s ep_en_start : 1;
} usbfs_depctl_expl_s;

_Static_assert(sizeof(usbfs_depctl_expl_s) == 4,
	       "Struct usbfs_depctl_expl_s defined error!");

static inline void usbfs_set_ep_ctl(usbfs_ep_re io_r, usbfs_ep_rre ep_rr,
				    usbfs_depctl_expl_s depctl) {
	union {
		usbfs_depctl_expl_s e;
		usbfs_depctl_s d;
	} ed = {
		.e = depctl,
	};
	usbfs_wreg_depctl_s(io_r, ep_rr, ed.d);
}

static inline usbfs_depctl_expl_s usbfs_get_ep_ctl(usbfs_ep_re io_r,
						   usbfs_ep_rre ep_rr) {
	union {
		usbfs_depctl_expl_s e;
		usbfs_depctl_s d;
	} ed = {
		.d = usbfs_rreg_depctl_s(io_r, ep_rr),
	};
	return ed.e;
}
